package dms.presentation.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.hibernate.StaleObjectStateException;

import dms.util.HibernateUtil;

/**
 * Servlet Filter implementation class CloseSessionInView
 */
public class CloseSessionInView implements Filter {
	private static Log log = LogFactory.getLog(CloseSessionInView.class);
	private SessionFactory sf;
    /**
     * Default constructor. 
     */
    public CloseSessionInView() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		try {
			log.debug("close session in view start");
			chain.doFilter(request, response);
			log.debug("if commit transaction not commit then commit");
			if (sf != null) {
				/*针对本系统原来并没有使用close session in view,所以这里先判断如果是以前的情况
				 * 则transaction已经关闭，如果是新的repository则transaction并没有commit，这里
				 * 需要关闭
				 */
				if (sf.getCurrentSession().getTransaction().isActive()) {
					sf.getCurrentSession().getTransaction().commit();
					//commit之后session会自动关闭
				}
			}
		} catch (StaleObjectStateException staleEx) {
			 log.error("This interceptor does not implement optimistic concurrency control!");
	            log.error("Your application will not work until you add compensation actions!");
	            // Rollback, close everything, possibly compensate for any permanent changes
	            // during the conversation, and finally restart business conversation. Maybe
	            // give the user of the application a chance to merge some of his work with
	            // fresh data... what you do here depends on your applications design.
	            throw new ServletException(staleEx);

		} catch (Exception ex) {
			ex.printStackTrace();
			try {
				if(sf.getCurrentSession().getTransaction().isActive()) {
					log.debug("回滚事务");
					sf.getCurrentSession().getTransaction().rollback();
				}
			} catch (Exception e) {
				log.error("无法回滚事务:" + e.getMessage());
				throw new ServletException(e);
			}
			
		}
	}
	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		log.debug("初始化Close session in view filter");
		sf = HibernateUtil.getSessionFactory();
	}

}
